<?php

namespace teach\components;

/**
 * 企业发红包给用户
 * Class WxPay
 * @package teach\components
 */
class WxPay
{
    /**
     * 发红包
     * @param $url
     * @param $obj
     * @return bool|mixed
     */
    public function payLuckyMoney($url, $obj)
    {
        //创建随机字符串(32位)
        $obj['nonce_str'] = $this->randStr();
        //创建签名
        $sign = $this->getSign($obj, false);
        //halt($sign);
        $obj['sign'] = $sign;    //将签名传入数组
        $postXml = $this->arrayToXml($obj);    //将参数转为xml格式
        //halt($postXml);
        $responseXml = $this->curl_post_ssl($url, $postXml);    //提交请求
        //halt($responseXml);
        return $responseXml;
    }

    //数组转xml
    function arrayToXml($arr) {
        $xml = "<xml>";
        foreach ($arr as $key=>$val) {
            if (is_numeric($val)) {
                $xml.="<".$key.">".$val."</".$key.">";
            } else {
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }

    //生成随机字符串，默认32位
    public function randStr($length=32) {
        //创建随机字符
        $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        $str = "";
        for($i=0;$i<$length;$i++) {
            $str.=substr($chars, mt_rand(0,strlen($chars)-1),1);
        }
        return $str;
    }

    /**
     * @param array $arr 生成前面的参数
     * @param $urlEncode
     * @return string 返回加密后的签名
     */
    public function getSign($arr, $urlEncode)
    {
        $buff = "";
        //对传进来的数组参数里面的内容按照字母顺序排序，a在前面，z在最后（字典序）
        ksort($arr);
        foreach ($arr as $k => $v) {
            if (null != $v && "null" != $v && "sign" != $k) {    //签名不要转码
                if ($urlEncode) {
                    $v = urlencode($v);
                }
                $buff .= $k . "=" . $v . "&";
            }
        }
        // 去掉末尾符号“&”，其实不用这个if，因为长度肯定大于0
        if (strlen($buff) > 0) {
            $stringA = substr($buff, 0, strlen($buff) - 1);
        }
        //签名拼接api
        $stringSignTemp = $stringA . "&key=" . config('wx_sh.key');//TODO 商户号md5key
        //签名加密并大写
        $sign = strtoupper(md5($stringSignTemp));
        return $sign;
    }


    //post请求网站，需要证书
    public function curl_post_ssl($url, $vars, $second = 30, $aHeader = array())
    {
        $ch = curl_init();
        //超时时间
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        //这里设置代理，如果有的话
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        //cert 与 key 分别属于两个.pem文件
        //请确保您的libcurl版本是否支持双向认证，版本高于7.20.1，相当于发curl验证【当前文件所在目录/cert/wxpay/】下的两个pem证书文件。
        curl_setopt($ch, CURLOPT_SSLCERT, dirname(__FILE__) . DIRECTORY_SEPARATOR . 'cert' . DIRECTORY_SEPARATOR . 'wxpay' . DIRECTORY_SEPARATOR . 'apiclient_cert.pem'); //TODO 证书位置
        curl_setopt($ch, CURLOPT_SSLKEY, dirname(__FILE__) . DIRECTORY_SEPARATOR . 'cert' . DIRECTORY_SEPARATOR . 'wxpay' . DIRECTORY_SEPARATOR . 'apiclient_key.pem'); //TODO 证书位置
        //curl_setopt($ch,CURLOPT_CAINFO,dirname(__FILE__).DIRECTORY_SEPARATOR.
        //    'cert'.DIRECTORY_SEPARATOR.'rootca.pem');    //这个不需要，因为大部分的操作系统都已经内置了rootca.pem证书了，就是常见的CA证书。
        if (count($aHeader) >= 1) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
        }
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);
        $data = curl_exec($ch);
        if ($data) {
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
            echo "call faild, errorCode:$error\n";
            curl_close($ch);
            return false;
        }
    }
}
